package gameCreation;

import hhAcademicBowl.Question;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;

public class GameCreator {

	private JFrame frame;
	private boolean doubleJeopardy = false;
	QData[][] normalQuestions = new QData[5][5];
	QData[][] doubleQuestions = new QData[5][5];
	String[] normalCategories = new String[5];
	String[] doubleCategories = new String[5];
	String finalQuestion, finalAnswer;
	final GameCreator gc = this;
	
	public boolean isDoubleJeopardy() {
		return doubleJeopardy;
	}

	JLabel lblNowEditing;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GameCreator window = new GameCreator();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GameCreator() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setBounds((screen.width-800)/2, (screen.height-700)/2, 800, 700);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.setBounds(0, 0, 784, 21);
		frame.getContentPane().add(menuBar);
		
		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);
		
		JMenuItem mntmSave = new JMenuItem("Save");
		mntmSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setFileFilter(new FileNameExtensionFilter("HHAC file", "hhac"));
				fileChooser.setAcceptAllFileFilterUsed(false);
				if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
				  File file = fileChooser.getSelectedFile(); //TODO force file extension
				  String name = file.getName();
				  if (name.indexOf('.')==-1) {
				  name += ".hhac";
				  file = new File(file.getParentFile(), name);
				  }
				  savetoFile(file);
				}
				
			}
		});
		mnFile.add(mntmSave);
		
		JMenuItem mntmLoad = new JMenuItem("Load");
		mntmLoad.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setFileFilter(new FileNameExtensionFilter("HHAC file", "hhac"));
				if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
				  File file = fileChooser.getSelectedFile();
				  loadFromFile(file);
				}
			}
		});
		mnFile.add(mntmLoad);
		
		JMenu mnEdit = new JMenu("Edit");
		menuBar.add(mnEdit);
		
		JMenuItem mntmNormalJeopardy = new JMenuItem("Normal Jeopardy");
		mntmNormalJeopardy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				setDoubleJeopardy(false);
			}
		});
		mnEdit.add(mntmNormalJeopardy);
		
		JMenuItem mntmDoubleJeopardy = new JMenuItem("Double Jeopardy");
		mntmDoubleJeopardy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setDoubleJeopardy(true);
			}
		});
		mnEdit.add(mntmDoubleJeopardy);
		
		JMenuItem mntmFinalJeopardy = new JMenuItem("Final Jeopardy"); 
		mntmFinalJeopardy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				FinalJeopardyEditor fje = new FinalJeopardyEditor(gc);
				fje.frame.setVisible(true);
			}
		});
		mnEdit.add(mntmFinalJeopardy);
		
		lblNowEditing = new JLabel("Editing: Normal Jeopardy");
		lblNowEditing.setFont(new Font("Tahoma", Font.PLAIN, 17));
		lblNowEditing.setBounds(10, 25, 202, 21);
		frame.getContentPane().add(lblNowEditing);
		
		drawCategoryPanels();
	}
	
	private void drawCategoryPanels(){
		JPanel gamePanel = new JPanel();
		gamePanel.setForeground(Color.BLACK);
		gamePanel.setBounds(0, 50, (frame.getWidth()), (frame.getHeight()-85));
		frame.getContentPane().add(gamePanel);
		gamePanel.setLayout(null);
		
		JTextField[] categories = new JTextField[5];
		
		int categoryWidth = ((gamePanel.getWidth()-60)/5);
		JPanel[] categoryPanels = new JPanel[5];
		
		//---------------------------------------------Category Paneling--------------------------------------------------------//
		for (int i = 0; i < categoryPanels.length; i++) {
			categoryPanels[i] = new JPanel();
			if(i<1){
				categoryPanels[i].setBounds(10, 0, categoryWidth, gamePanel.getHeight());
			}
			else{
				categoryPanels[i].setBounds(categoryPanels[i-1].getX()+categoryWidth+10, 0, categoryWidth, gamePanel.getHeight());
			}
			gamePanel.add(categoryPanels[i]);
			categoryPanels[i].setLayout(null);
			
			categories[i] = new JTextField();
			categories[i].setBounds(5, 5, categoryWidth - 10, 30);
			categories[i].setFont(new Font("Tahoma", Font.PLAIN, 25));
			final JTextField f_category = categories[i];
			final int f_i = i;
			categories[i].addFocusListener(new FocusAdapter() {
				@Override
				public void focusLost(FocusEvent arg0) {
					if(doubleJeopardy){
						doubleCategories[f_i] = f_category.getText();
					}
					else{
						normalCategories[f_i] = f_category.getText();
					}
					
				}
			});
			categoryPanels[i].add(categories[i]);
			
			
			//Buttons loops and handling
			int buttonBuffer = (categoryPanels[i].getHeight() - (45) - (85 * 5)) / 5;
			JButton[] buttonsTmp = new JButton[5];
			
			for (int j = 0; j < buttonsTmp.length; j++) {
				
				if(doubleJeopardy){ //adjust # for DJ
					buttonsTmp[j] = new JButton(new Integer((j+1)*20).toString());
				}
				else{
					buttonsTmp[j] = new JButton(new Integer((j+1)*10).toString());
				}
				
				
				buttonsTmp[j].setFont(new Font("Impact", Font.PLAIN, 22));
				if(j<1){ //first button
					buttonsTmp[j].setBounds(10, ((categories[i].getY() + categories[i].getHeight()) + buttonBuffer), categoryWidth-20, 85);
				}
				else{    //the rest of them
					buttonsTmp[j].setBounds(10, ((buttonsTmp[j-1].getY() + buttonsTmp[j-1].getHeight()) + buttonBuffer),categoryWidth-20, 85);
				}
				
				//These final vars are basically work-arounds so I can reference a button from within it's own ActionListener
				//it's kinda janky...
				final int btnNum = j;
				final int catNum = i;
				final JButton btn = buttonsTmp[j];
				final GameCreator gc = this;
				
				ActionListener l = new ActionListener() {	
					@Override
					public void actionPerformed(ActionEvent arg0) {
						questionEditor x = new questionEditor(catNum, btnNum, Integer.parseInt(btn.getText()), gc);
						x.frame.setVisible(true);
						//I hope thats it...
					}
				};
				buttonsTmp[j].addActionListener(l);
				
				categoryPanels[i].add(buttonsTmp[j]);
			}
			
			
		}
	}
	
	public void setDoubleJeopardy(boolean v) {
		if(v){
			doubleJeopardy = true;
			lblNowEditing.setText("Editing: Double Jeopardy");
			for(int i = 0; i < 5;i++){ //Edits button values
				for(int j = 0; j < 5; j++){
					JPanel gp = (JPanel) frame.getContentPane().getComponent(2);
					( (JButton) ((JPanel) gp.getComponent(i)).getComponent(1 + j)).setText(new Integer((j+1)*20).toString());
				}
			}
			for(int c = 0; c<5;c++){
				JPanel gp = (JPanel) frame.getContentPane().getComponent(2);
				((JTextField) ((JPanel) gp.getComponent(c)).getComponent(0)).setText(doubleCategories[c]);
			}
		}
		else{
			doubleJeopardy = false;
			lblNowEditing.setText("Editing: Normal Jeopardy");
			for(int i = 0; i < 5;i++){ //loops through all of the 
				for(int j = 0; j < 5; j++){
					JPanel gp = (JPanel) frame.getContentPane().getComponent(2);
					( (JButton) ((JPanel) gp.getComponent(i)).getComponent(1 + j)).setText(new Integer((j+1)*10).toString());
				}
			}
			for(int c = 0; c<5;c++){ //Edits category boxes
				JPanel gp = (JPanel) frame.getContentPane().getComponent(2);
				((JTextField) ((JPanel) gp.getComponent(c)).getComponent(0)).setText(normalCategories[c]);
			}
			
		}
		
	}
	
	
	/*
	 * NOTE: the unicode characters below are important
	 * \u001f is the entry delimiter (replacing : and ; in V1.0)
	 * \u001e is the data delimiter (replacing , in V1.0)
	 */
	public void savetoFile(File file) {
		try {
			//FileWriter output = new FileWriter(file);
			FileOutputStream os = new FileOutputStream(file);
			OutputStreamWriter output = new OutputStreamWriter(os, "UTF-8");
			
			//normal Jeopardy
			output.write("!\u001fnormal Qs\u001f\r\n");
			for(int cat = 0; cat < 5; cat++){
				
				if(normalCategories[cat] != null)
					output.write("@\u001f" + normalCategories[cat] + "\u001f\r\n");
				else
					output.write("@\u001f\u001f\r\n");
				
				for(int que = 0; que < 5; que++){
					if(normalQuestions[cat][que] != null) //accouts for blanks
						output.write(normalQuestions[cat][que].toSaveString(false));
					else{
						output.write("#\u001f\u001f\r\n");
					}
				}
				output.write("\n");
			}
			
			//doube jeopardy
			output.write("!\u001fdouble Jeopardy\u001f\r\n");
			for(int cat = 0; cat < 5; cat++){
				if(doubleCategories[cat] != null)
					output.write("$\u001f" + doubleCategories[cat] + "\u001f\r\n");
				else
					output.write("$\u001f\u001f\r\n");
				
				
				for(int que = 0; que < 5; que++){ //accounts for blanks
					if(doubleQuestions[cat][que] != null)
						output.write(doubleQuestions[cat][que].toSaveString(true));
					else{
						output.write("%\u001f\u001f\r\n");
					}
				}
				output.write("\n");
			}
			
			//final jeopardy
			if(finalQuestion != null)
				output.write("&\u001f" + finalQuestion + "\u001f\r\n");
			else
				output.write("&\u001f\u001f\r\n");
			
			if(finalAnswer != null)
				output.write("~\u001f" + finalAnswer + "\u001f\r\n");
			else
				output.write("~\u001f\u001f\r\n");
			
			output.close();
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	/*
	 * NOTE: the unicode characters below are important
	 * \u001f is the entry delimiter (replacing : and ; in V1.0)
	 * \u001e is the data delimiter (replacing , in V1.0)
	 */
	public void loadFromFile(File file) {
		try {
			
			InputStream f = new FileInputStream(file);
			Scanner input = new Scanner(f, "UTF-8");
			input.useDelimiter("\u001f");
			
			int que = 0;
			int cat = -1; //janky fix so it's 0-indexed see below
			
			while(input.hasNext()){
				
				String val = input.next().replaceAll("\n|\r\n", "");
				if(val.equals("!")){ //game (double or single jeopardy
					input.next().replaceAll("\n|\r\n", "");
					que = 0;
					cat = -1;
				}
				else if(val.equals("@")){ //normal category
					que = 0;
					cat++;
					normalCategories[cat] = input.next().replaceAll("\n|\r\n", "");
				}
				else if(val.equals("#")){
					String[] qData = input.next().replaceAll("\n|\r\n", "").split("\u001e");
					
					try {
						int value = Integer.parseInt(qData[2]);
						boolean dd = Boolean.parseBoolean(qData[3]);
						normalQuestions[cat][que] = new QData(qData[0], qData[1], value, dd);
					} catch (ArrayIndexOutOfBoundsException e) {
						
						System.out
								.println("Blank q at: " + cat + ", " + que);
					}
					
				
					que++;
				}
				else if(val.equals("$")){
					que = 0;
					cat++;
					doubleCategories[cat] = input.next().replaceAll("\n|\r\n", "");
				}
				else if(val.equals("%")){
					String[] qData = input.next().replaceAll("\n|\r\n", "").split("\u001e");
					
					
					try {
						int value = Integer.parseInt(qData[2]);
						boolean dd = Boolean.parseBoolean(qData[3]);
						doubleQuestions[cat][que] = new QData(qData[0], qData[1], value, dd);
					} catch (ArrayIndexOutOfBoundsException e) {
						
						System.out
								.println("Blank Q at " + cat + ", " + que);
					}
					
					
					que++;
				}
				else if(val.equals("&")){
					//finaljeo.finalJeopardyQ = input.next().replaceAll("\n|\r\n", "");
					finalQuestion = (input.next().replaceAll("\n|\r\n", ""));
				}
				else if(val.equals("~")){
					//finaljeo.finalJeopardyA = input.next().replaceAll("\n|\r\n", "");
					finalAnswer = (input.next().replaceAll("\n|\r\n", ""));
				}
				
				
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		//put the categories in thier boxes
		
		for(int c = 0; c<5;c++){ //Edits category boxes
			JPanel gp = (JPanel) frame.getContentPane().getComponent(2);
			((JTextField) ((JPanel) gp.getComponent(c)).getComponent(0)).setText(normalCategories[c]);
		}
	}
}
